package edu.friday.service.impl;

import edu.friday.common.constant.UserConstants;
import edu.friday.common.result.TableDataInfo;
import edu.friday.model.SysUserEntity;
import edu.friday.model.vo.SysUserVO;
import edu.friday.repository.SysUserRepository;
import edu.friday.repository.SysUserRoleRepository;
import edu.friday.service.SysUserService;
import edu.friday.common.utils.BeanUtils;
import edu.friday.common.utils.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.*;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Arrays;
import java.util.List;
import java.util.Optional;

/**
 * 用户表业务层
 */
@Service
public class SysUserServiceImpl implements SysUserService {

    @Autowired
    SysUserRepository userRepository;

    @Autowired
    SysUserRoleRepository userRoleRepository;

    @Override
    public TableDataInfo selectUserList(SysUserVO user, Pageable page) {
        SysUserEntity sysUser = new SysUserEntity();
        BeanUtils.copyPropertiesIgnoreEmpty(user, sysUser);
        sysUser.setDelFlag("0");
        ExampleMatcher exampleMatcher = ExampleMatcher.matching()
                .withMatcher("userName", ExampleMatcher.GenericPropertyMatchers.contains())
                .withMatcher("phonenumber", ExampleMatcher.GenericPropertyMatchers.contains());
        Example<SysUserEntity> example = Example.of(sysUser, exampleMatcher);
        Page<SysUserEntity> rs = userRepository.findAll(example, page);
        return TableDataInfo.success(rs.toList(), rs.getTotalElements());
    }

    @Override
    public String checkUserNameUnique(String userName) {
        SysUserEntity sysUser = new SysUserEntity();
        sysUser.setUserName(userName);
        return count(sysUser);
    }

    @Override
    public String checkPhoneUnique(SysUserVO userInfo) {
        SysUserEntity user = new SysUserEntity();
        BeanUtils.copyProperties(userInfo, user);
        return checkUnique(user);
    }

    @Override
    public String checkEmailUnique(SysUserVO userInfo) {
        SysUserEntity user = new SysUserEntity();
        BeanUtils.copyProperties(userInfo, user);
        return checkUnique(user);
    }

    @Override
    @Transactional
    public boolean insertUser(SysUserVO userVO) {
        SysUserEntity sysUser = new SysUserEntity();
        BeanUtils.copyProperties(userVO, sysUser);
        sysUser.setDelFlag("0");
        // 新增用户信息
        userRepository.save(sysUser);
        userVO.setUserId(sysUser.getUserId());
        // 新增用户与角色管理
        insertUserRole(userVO);
        return null != sysUser.getUserId();
    }

    @Override
    @Transactional
    public int deleteUserByIds(Long[] userIds) {
        return userRepository.deleteUserByIds(userIds);
    }

    @Override
    @Transactional
    public boolean updateUser(SysUserVO userVO) {
        Long userId = userVO.getUserId();
        Optional<SysUserEntity> op = userRepository.findById(userId);
        if (op.isEmpty()) return false;
        // 删除用户与角色关联
        userRepository.deleteUserRoleByUserId(userId);
        SysUserEntity sysUser = op.get();
        BeanUtils.copyPropertiesIgnoreNull(userVO, sysUser);
        // 更新用户信息
        userRepository.save(sysUser);
        // 新增用户与角色关联
        insertUserRole(userVO);
        return null != sysUser.getUserId();
    }

    @Override
    public SysUserEntity selectUserById(Long userId) {
        SysUserEntity sysUser = new SysUserEntity();
        sysUser.setUserId(userId);
        sysUser.setDelFlag("0");
        Optional<SysUserEntity> one = userRepository.findOne(Example.of(sysUser));
        return one.orElse(null);
    }

    @Override
    public SysUserEntity selectUserByUserName(String username) {
        SysUserEntity sysUser = new SysUserEntity();
        sysUser.setUserName(username);
        sysUser.setDelFlag("0");
        Example<SysUserEntity> example = Example.of(sysUser);
        return findOne(example);
    }

    private String count(SysUserEntity sysUser) {
        Example<SysUserEntity> example = Example.of(sysUser);
        long count = userRepository.count(example);
        if (count > 0) {
            return UserConstants.NOT_UNIQUE;
        }
        return UserConstants.UNIQUE;
    }

    private String checkUnique(SysUserEntity user) {
        long userId = StringUtils.isNull(user.getUserId()) ? -1L : user.getUserId();
        Example<SysUserEntity> example = Example.of(user);
        SysUserEntity info = findOne(example);
        if (StringUtils.isNotNull(info) && info.getUserId() != userId) {
            return UserConstants.NOT_UNIQUE;
        }
        return UserConstants.UNIQUE;
    }

    private SysUserEntity findOne(Example<SysUserEntity> example) {
        List<SysUserEntity> list = userRepository.findAll(example, PageRequest.of(0, 1)).toList();
        if (list.isEmpty()) {
            return null;
        }
        return list.get(0);
    }

    @Transactional
    public void insertUserRole(SysUserVO user) {
        Long[] roleIds = user.getRoleIds();
        if (StringUtils.isNull(roleIds) || roleIds.length == 0) {
            return;
        }
        Long[] longs = new Long[roleIds.length];
        Arrays.fill(longs, user.getUserId());
        userRepository.batchInsertUserRole(longs, roleIds);
    }

}
